#pragma once

#include <stdint.h>

struct BaseGraph;
struct LDPC_Matrix;

BaseGraph Load_LDPC_BG(void);
void Free_LDPC_BG(BaseGraph& bg);

bool Load_LDPC_Matrix(LDPC_Matrix& matrix, const int K, const float Rate);
void Free_LDPC_Matrix(LDPC_Matrix& matrix);

/*
* Base Graph 1 & 2
*/
struct BaseGraph {
	// size of BG1 & BG2
	uint32_t BG1_Row, BG1_Col;
	uint32_t BG2_Row, BG2_Col;

	// index of NonZero elements
	uint32_t* BG1_index, * BG1_Z1, * BG1_Z2, * BG1_Z3, * BG1_Z4, * BG1_Z5, * BG1_Z6, * BG1_Z7, * BG1_Z8;
	uint32_t* BG2_index, * BG2_Z1, * BG2_Z2, * BG2_Z3, * BG2_Z4, * BG2_Z5, * BG2_Z6, * BG2_Z7, * BG2_Z8;
	uint32_t* Zc;
};

struct LDPC_Matrix {
	// Base Graph Parameters
	int BG_Choosen = 0; // Base Graph
	int Kb = 0, Zc = 0, a_idx = 0;

	// Target LDPC Parameter
	int nbrOfInfoBits = 0;
	int nbrOfCheckBits = 0;
	int beginOfCheckBit = 0;
	float Rate = 0;

	// Position of Nonzero Elements
	// Size of H
	// H - Check Matrix
	// H - Check Matrix for Core Check Matrix
	// H - Check Matrix for Expand Check Matrix
	int nbrOfRow = 0, nbrOfCol = 0;
	uint32_t H_NonzeroElements = 0, H_Base_NonzeroElements = 0, H_Expand_NonzeroElements = 0;
	uint32_t* H_Row_Index = nullptr, * H_Col_Index = nullptr;
	uint32_t* H_Base_Row_Index = nullptr, * H_Base_Col_Index = nullptr;
	uint32_t* H_Expand_Row_Index = nullptr, * H_Expand_Col_Index = nullptr;

	// Position of Nonzero Elements
	// Size of H
	// H - Check Matrix for Complete Check Matrix
	uint32_t H_Complete_NonzeroElements = 0;
	uint32_t* H_Complete_Row_Index = nullptr, * H_Complete_Col_Index = nullptr;

	// Connection between VN & CN
	uint32_t* IdxConnectQij = nullptr, * IdxConnectRji = nullptr;
	uint32_t* IdxConnectQij_idx = nullptr, * IdxConnectRji_idx = nullptr;
};